#!/usr/bin/env python3.10
# -*- encoding: utf-8 -*-
'''
@File    :   controllers.py
@Time    :   2024/02/06 11:10:40
@Author  :   windstarry 
@Version :   1.0
'''
# here put the import lib
from datetime import datetime

from django.contrib.auth import get_user_model, authenticate
from ninja_extra import api_controller, route, status
from ninja_extra.permissions import IsAdminUser, IsAuthenticated

from ninja_jwt import schema
from ninja_jwt.authentication import JWTAuth
from ninja_jwt.controller import TokenObtainSlidingController
from ninja_jwt.tokens import SlidingToken
from .schema import (
    LoginSchema,
    UserInfoSchema,
    UserTokenOutSchema,
)
User = get_user_model()


@api_controller("/users", tags=["用户管理"],auth=JWTAuth())
class UserController:
    @route.get(
        "/info",
        summary="用户信息",
        url_name="userinfo",
        response = {201: UserInfoSchema},
        permissions=[IsAuthenticated],
    )
    def get_user_info(self,):
        """
        获取用户信息

        :return: UserRetrieveSchema对象,包含用户信息
        """
        user_obj = self.context.request.user
        return user_obj
    
    
    
@api_controller("/auth", tags=["认证"])
class UserTokenController(TokenObtainSlidingController):

    @route.post("/login", response=UserTokenOutSchema, summary="登录", url_name="login")
    def obtain_token(self, auth: LoginSchema):
        """
        获取用户对象并生成令牌
        Args:
            auth (LoginSchema): 用户登录信息
        Returns:
            UserTokenOutSchema: 包含用户对象、令牌和过期时间的输出对象
        """
        # 获取用户对象
        user_obj = authenticate(username=auth.username, password=auth.password)
        # 生成令牌
        token = SlidingToken.for_user(user_obj)
        return UserTokenOutSchema(
            user=user_obj,
            token=str(token),
            token_exp_date=datetime.fromtimestamp(token["exp"]),
        )

    @route.post(
        "/api-token-refresh",
        response=schema.TokenRefreshSlidingSerializer,
        summary="刷新token",
        url_name="refresh",
    )
    def refresh_token(self, refresh_token: schema.TokenRefreshSlidingSchema):
        """
        刷新令牌

        参数:
            refresh_token (schema.TokenRefreshSlidingSchema): 用于刷新令牌的参数对象

        返回:
            refresh (schema.TokenRefreshSlidingSchema): 刷新后的令牌对象
        """
        refresh = schema.TokenRefreshSlidingSerializer(**refresh_token.dict())
        return refresh

